﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using StarLabel.label.item;
namespace StarLabel.label
{
    /// <summary>
    /// Copyright 2019  ZhengJi. All Rights Reserved.
    /// 打印控制类
    /// 根据提供的数据和模板打印标签
    /// </summary>
    public class StarLabelPrint
    {
        /// <summary>
        /// 注册插件item
        /// </summary>
        /// <param name="itemName">标签名称,对于XMLElement Name属性</param>
        /// <param name="classNameSpace"> 格式：DllName,classNameSpace</param>
        public static void RegisterItem(string itemName, string classNameSpace)
        {
            ItemManager.RegisterItem(itemName, classNameSpace);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataList">要打印的数据，一个Map表示一列</param>
        /// <param name="printerName">打印机名称</param>
        /// <param name="Density">打印浓度</param>
        /// <param name="templateName">模板</param>
        public static void printData(List<Hashtable> dataList, string printerName,  string templateName, PrintParam pParam)
        {

            if (pParam == null) pParam = PrintParam.DefaultPrintParam();

            Label lblDefine = Label.parseFromTemplate(templateName);
            List<Hashtable> listRow  = new List<Hashtable>(); ;

            int iCount = 0;
            for (int i = 0; i < dataList.Count; i++)
            {
                
                listRow.Add(dataList[i]);

                if (pParam.StartColumn>0 && i==(lblDefine.LabelsPerRow-pParam.StartColumn-1))//设定从第几个标签打印
                {
                    printSingleRow(listRow, printerName, lblDefine, pParam);
                    listRow.Clear();
                    iCount = 0;
                    pParam.StartColumn = 0;

                    continue;
                }
                if ((iCount + 1)% lblDefine.LabelsPerRow == 0 )
                {
                    
                    printSingleRow(listRow, printerName,  lblDefine, pParam);
                    listRow.Clear();
                }

                iCount++;

            }
            if (listRow !=null && listRow.Count > 0)
            {
               // pParam.LabelsPerRow = listRow.Count;
                printSingleRow(listRow, printerName,  lblDefine, pParam);
            }

            

        }
        /// <summary>
        /// 打印单行
        /// </summary>
        /// <param name="dataList">一条记录一列</param>
        /// <param name="printerName">打印机名称</param>
        /// <param name="density">打印浓度</param>
        /// <param name="lblDefine">标签定义</param>
        private static void  printSingleRow(List<Hashtable> dataList, string printerName,  Label lblDefine, PrintParam pParam)
        {
            

            float pageWidth =   float.Parse(lblDefine.Width) * lblDefine.LabelsPerRow + float.Parse(lblDefine.GapHorizontal) * (lblDefine.LabelsPerRow - 1)+float.Parse(lblDefine.OffsetLength)*2;

            
            float pageHeight = float.Parse(lblDefine.Height) + float.Parse(lblDefine.GapVertical); 
            TSCPrint.openport(printerName);

            TSCPrint.setup(pageWidth.ToString(), pageHeight.ToString(), pParam.Speed, pParam.Density, pParam.Sensor, lblDefine.GapVertical,pParam.Offset);

            TSCPrint.sendcommand(string.Format("DIRECTION {0}",lblDefine.Direction));
            TSCPrint.clearbuffer();


            int indexCol = pParam.StartColumn;
            for (int i = 0; i < dataList.Count; i++)
            {
                Hashtable ht = dataList[i];
                foreach(Item it in lblDefine.Items)
                {
                   
                    float itemX = calcItemPositionX(it, pParam, lblDefine, indexCol);//计算X坐标
                    printItem(ht, it, itemX);

                }
                indexCol++;

            }

            TSCPrint.printlabel("1", "1");
            TSCPrint.closeport();
            
        }
        /// <summary>
        /// 打印单个Label
        /// </summary>
        /// <param name="ht"></param>
        /// <param name="it"></param>
        /// <param name="positionX"></param>
        /// <param name="positionY"></param>
        private static void printItem(Hashtable ht, Item it,float itemX)
        {
            string labelText = it.Text;
            if (!string.IsNullOrEmpty(it.DataField))
            {
                labelText = ht[it.DataField] as string;
            }
                     
            float itemY = float.Parse(it.Y);

            it.DrawLabel(itemX, itemY, labelText,it.Rotation);

           
          
        }

        /// <summary>
        /// 计算item的x 坐标
        /// </summary>
        /// <param name="it">打印ITEM</param>
        /// <param name="pParam">打印参数</param>
        /// <param name="lblDefine">标签定义</param>
        /// <param name="indexColumn">打印第几列标签，序号从0开始</param>
        /// <returns></returns>
        private static float calcItemPositionX(Item it, PrintParam pParam, Label lblDefine, int indexColumn)
        {
             if (indexColumn==0) return float.Parse(it.X);

            float itemX = float.Parse(it.X);

   

            
           
              if (it.Rotation.Equals("180"))
            {
                float w = float.Parse(lblDefine.Width) * (indexColumn + 1) + float.Parse(lblDefine.GapHorizontal) * indexColumn + float.Parse(lblDefine.OffsetLength);//从最边框到indexColumn的X值
                w = w * pParam.UnitToPoint;

                float offset = (float.Parse(lblDefine.Width) + float.Parse(lblDefine.OffsetLength)) * pParam.UnitToPoint - itemX;//计算item在标签中的offset
                itemX =  w- offset;
            }
            else
            {
                float w = float.Parse(lblDefine.Width) * (indexColumn ) + float.Parse(lblDefine.GapHorizontal) * indexColumn + float.Parse(lblDefine.OffsetLength);//从最边框到indexColumn的X值
                w = w * pParam.UnitToPoint;

               // float offset = (float.Parse(lblDefine.Width) + float.Parse(lblDefine.OffsetLength)) * pParam.UnitToPoint - itemX;//计算item在标签中的offset
                itemX = w + float.Parse(it.X);
            }
             

            return itemX;

            
        }
    }
}
